iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 6
0
自我挑戰組

寫遊戲初體驗系列 第 6

Day6 基本的遊戲循環

  • 分享至 

  • xImage
  •  

遊戲循環

遊戲的循環跟一般我們在學校寫的程式不太相同,我們在學校寫的程式會等待使用者的輸入,然後給予反饋,就像相聲一樣。當你停在那不做任何動作的時候,他也會停在那裏。

就像這樣

while(true) {

    std::cin >> command;
    handleCommand(command);
}

但遊戲載沒有玩家輸入的時候,也能夠持續進行。如果只是擺著不動看著螢幕,遊戲是不會凍結的。遊戲循環是處理使用者輸入,而不是等待他。

while(true) {

    processInput();
    update();
    render();
}
  • processInput
    • 處理使用者輸入
  • update
    • 更新遊戲物理、AI
  • render
    • 繪製遊戲

基本的遊戲循環就是這樣了。

但這裡有個小問題,我們這樣無法控制遊戲運行的快慢,在快的CPU他跑得飛快,在慢的CPU上他會超慢。

每台電腦的性能不一樣,每個frame所花費的時間也會不同,但是現實所逝去的時間是相同的。所以我們可以根據上一個frame到現在所花費的時間來進行更新,這樣可以保證快慢的電腦所花費的時間是一樣的喔。

double lastTime = getCurrentTime();
while (true)
{
    double current = getCurrentTime();
    double elapsed = current - lastTime;
    processInput();
    update(elapsed);
    render();
    lastTime = current;
}

我們也可以利用固定的時間間隔來更新時間,這樣處理會比較簡單,物理和AI也會更加的穩定。
我們的遊戲自上次循環經過了一定量的真實時間,需要為遊戲的“當前時間”模擬推進相同長度的時間,以追上玩家的時間。

double previous = getCurrentTime();
double lag = 0.0;
while (true)
{
    double current = getCurrentTime();
    double elapsed = current - previous;
    previous = current;
    lag += elapsed;

    processInput();

    while (lag >= MS_PER_UPDATE)
    {
        update(MS_PER_UPDATE);
        lag -= MS_PER_UPDATE;
    }

    render();
}

在每幀的開始,根據過去了多少真實的時間,更新lag。 lag表明遊戲世界時間比真實世界落後了多少,然後我們使用一個**固定時間步長(fix time step)**的內部循環進行追趕。 一旦我們追上真實時間,我們就渲染然後開始新一輪循環。

當然方法不止這些,要使用哪種方法也看場合會有所不同。

明天我們會來寫我們的game class,並且在之後慢慢搭建一個遊戲的雛形框架。


上一篇
Day5 SFML input
下一篇
Day 7 Game Class
系列文
寫遊戲初體驗30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言